/**
 * @Copyright ®2015 Sinosoft Co. Ltd. All rights reserved.<br/>
 * 项目名称 : 电子商务云服务平台
 * 创建日期 : 2016年6月28日
 * 修改历史 : 
 *     1. [2016年6月30日]修改文件 by chihouliang
 * 添加Javadoc注释，更新代码规范，静态工具类增加private构造函数
 */
package com.gavinwind.inspay.common.util;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * 
 * 【SocketFactory工厂工具类】
 * @author 
 * @date 2016年6月29日 上午11:57:18 
 * @version 1.0
 */
public class HttpsSecureProtocolSocketFactory implements SecureProtocolSocketFactory {

    /**ssl证书*/
    private SSLContext sslcontext = null;

    private SSLContext createSSLContext() {
        SSLContext tSslcontext = null;
        try {
            tSslcontext = SSLContext.getInstance("SSL");
            tSslcontext.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return tSslcontext;
    }

    private SSLContext getSSLContext() {
        if (this.sslcontext == null) {
            this.sslcontext = createSSLContext();
        }
        return this.sslcontext;
    }

    /**
     * 
     */
    public Socket createSocket(Socket cSocket, String cHost, int cPort, boolean cAutoClose) throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(cSocket, cHost, cPort, cAutoClose);
    }

    /**
     * 
     */
    public Socket createSocket(String cHost, int cPort) throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(cHost, cPort);
    }

    /**
     * 
     */
    public Socket createSocket(String cHost, int cPort, InetAddress cClientHost, int cLientPort) throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(cHost, cPort, cClientHost, cLientPort);
    }

    /**
     * 
     */
    public Socket createSocket(String cHost, int cPort, InetAddress cLocalAddress, int cLocalPort, HttpConnectionParams cParams)
            throws IOException, UnknownHostException, ConnectTimeoutException {
        if (cParams == null) {
            throw new IllegalArgumentException("Parameters may not be null");
        }
        int tTimeout = cParams.getConnectionTimeout();
        SocketFactory tSocketfactory = getSSLContext().getSocketFactory();
        if (tTimeout == 0) {
            return tSocketfactory.createSocket(cHost, cPort, cLocalAddress, cLocalPort);
        } else {
            Socket tSocket = tSocketfactory.createSocket();
            SocketAddress tLocaladdr = new InetSocketAddress(cLocalAddress, cLocalPort);
            SocketAddress tRemoteaddr = new InetSocketAddress(cHost, cPort);
            tSocket.bind(tLocaladdr);
            tSocket.connect(tRemoteaddr, tTimeout);
            return tSocket;
        }
    }

    // 自定义私有类
    private static class TrustAnyTrustManager implements X509TrustManager {

        public void checkClientTrusted(X509Certificate[] cChain, String cAuthType) throws CertificateException {}

        public void checkServerTrusted(X509Certificate[] cChain, String cAuthType) throws CertificateException {}

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }
    }
}
